<?php
/**
 * 订单控制器
 * Created by PhpStorm.
 * User: lz
 * Date: 2015/6/30
 * Time: 11:45
 */
class OrderApp extends MallbaseApp {

    private $common;
    /**
     * OrderApp constructor.
     */
    public function __construct()
    {
        $this->common = new CommonApp();
    }

    /**
     * 生成订单
     * @author jyx
     * @date 2015/11/05
     */
    public function add() {
        $action = '生成订单';
        setLogParameter($action);
        $method = strtoupper($_SERVER['REQUEST_METHOD']);
        $version = $_SERVER['HTTP_VERSION'];
        if ($method != 'POST') {
            $this->ajax_return(FLAG_ERROR, '非法的请求！');
        }
//        if (!$user_id = $this->checkLogin()) {
//            $this->ajax_return(ERROR_LOGIN, '请您进行登陆！');
//        }
//        $user_id = 539913;
//        $version = 'HeShe/1.4';
        //如果是最新版本
        if ($version == IOS_VERSION) {
            $data = $this->_addOrder($user_id, 0, '支付宝', 'alipay', S_IOS);
            if (!$data) {
                $this->ajax_return(FLAG_ERROR, '添加订单失败！');
            }
            //使用了优惠券,不需要付款的情况下
            if ($data['order_amount'] == 0) {
                $this->ajax_return(FLAG_ANOTHER, '不需要去付款！');
            }
            $this->ajax_return(FLAG_OK, '', $data);
        } else {
            $bases_info = $this->add_order($user_id, 0, '支付宝', 'alipay', S_IOS);
//        $bases_info[0]['order_amount'] = 0.01;
            $this->ajax_return(FLAG_OK, '操作成功！', $bases_info);
        }

    }


    /**
     * 微信生成订单
     * @author jiayanxiu
     * @date 2015/11/05
     */
    public function wxadd() {
        $action = '微信生成订单';
        setLogParameter($action);
        include_once(ROOT_PATH."/includes/payments/WxPayPubHelper/WxPay.pub.config.php");
        include_once(ROOT_PATH."/includes/payments/WxPayPubHelper/WxPayPubHelper.php");
        $method = strtoupper($_SERVER['REQUEST_METHOD']);
        $version = $_SERVER['HTTP_VERSION'];
        if ($method != 'POST') {
            $this->ajax_return(FLAG_ERROR, '非法的请求！');
        }
        if (!$user_id = $this->checkLogin()) {
            $this->ajax_return(ERROR_LOGIN, '请您进行登陆！');
        }
//        $version = 'HeShe/1.4';
//        $user_id = 101252;
        //如果是最新版本
        if ($version == IOS_VERSION) {
            $order = $this->_addOrder($user_id, 1, '微信', 'wxpay', S_IOS);
            if (!$order) {
                $this->ajax_return(FLAG_ERROR, '添加订单失败！');
            }
            $info['body'] = addslashes($order['goods'][0][1][0]['goods_name']);
            $info['order_sn'] = $order['pay_sn'];
            $info['order_amount'] = $order['order_amount'];
        } else {
            //插入订单信息
            $basesInfo = $this->add_order($user_id, 1, '微信', 'wxpay', S_IOS);
            $info = $basesInfo[0];
        }
        //使用了优惠券,不需要付款的情况下
        if ($info['order_amount'] == 0) {
            $this->ajax_return(FLAG_ANOTHER, '不需要去付款！');
        }
        //微信支付body最多只能五十个字符
        $info['body'] = mb_substr(str_replace(array('/',' '), '', $info['body']), 0, 50, 'utf8');
        //微信统一下单
        $input = new UnifiedOrder_pub();
        $input->setParameter('body',"He She Trends商城购物");
        $input->setParameter('out_trade_no', $info["order_sn"]);
        $input->setParameter('total_fee', floatval($info["order_amount"] * 100));
//        $input->setParameter('total_fee', 1);
        $input->setParameter('time_start', date("YmdHis"));
        $input->setParameter('time_expire', date("YmdHis", time() + 600));
        $input->setParameter('notify_url', WxPayConf_pub::NOTIFY_URL);
        $input->setParameter('trade_type', 'APP');
        $row = $input->getPrepayId();
        if ($row['return_code'] != 'SUCCESS' && $row['result_code'] != 'SUCCESS') {
            $this->ajax_return(FLAG_ERROR, '微信支付失败！');
        }

        $timestamp = time();
        $res['timestamp']    = $timestamp;
        $res['appid']        = $row['appid'];
        $res['partnerid']    = $row['mch_id'];
        $res['noncestr']     = $row['nonce_str'];
        $res['prepayid']     = $row['prepay_id'];
        $res['package']      = 'Sign=WXPay';
        $res['sign'] = $input->getSign($res);
        $this->ajax_return(FLAG_OK, '操作成功！', $res);
    }

    /**
     * 添加订单,1.4版本使用
     * @param $user_id
     * @param $payment_id:支付方式的id,0表示支付宝支付,1表示微信支付
     * @param $payment_name
     * @param $payment_code
     * @param $source:订单来源:来自IOS端,微信端,PC端
     * @return array
     * @author jyx
     * @date 2015/11/05
     */
    private function _addOrder($user_id, $payment_id, $payment_name, $payment_code, $source) {
        $spec_id    = $this->get_gp('spec_id', 'P');//商品扩展属性的id，比如：1,3,4,56
        if(!$spec_id){
            $this->ajax_return(FLAG_ERROR, '没有添加商品！');
        }
        $type = $this->get_gp('type', 'P');//判断是从购物车中来的商品还是单品信息,1:是,0:不是
        if($type==1){
            $quantity = $this->get_gp('quantity', 'P');//如果买的是单品则要传数量
        }
//        $spec_id = 6544;
//        $quantity = 1;
//        $type = 0;
        $coupon_id  = $this->get_gp('coupon_id', 'P');//优惠卷的id
        $shipping_name = $this->get_gp('shipping_name', 'P');//快递名称,没有可不传
        $post_script = $this->get_gp('post_script', 'P');//订单的总留言,比如:这是我的信息，这个要个好看点的，这是我的订单,每条留言用逗号分隔开
        $postScript = explode(',', $post_script);
        $model = m('goods');
        $order_amount = 0;//总费用
        //判断商品库存信息
        $this->checkStocks($model, $user_id, $type, $spec_id, $quantity);
        //获取商品信息
        $list = $this->_getGoodsInfo($model, $type, $user_id, $spec_id, $quantity);
        $model->begin();//开启事物
        //生成订单信息
        if ($list) {
            $coupon_info = array();
            //计算优惠卷
            $couponsModel = m('coupons');//优惠券对象
            if ($coupon_id) {
                $coupon_info = $couponsModel->getCouponsInfo($coupon_id);
                if (time() < $coupon_info['co_start_time'] && time() > $coupon_info['co_end_time']) {
                    $this->ajax_return(FLAG_ERROR, '您的优惠卷已经过期！');
                }
                if ($coupon_info['uid'] != $user_id) {
                    $this->ajax_return(FLAG_ERROR, '不是本人的优惠卷！');
                }
                /*//获取当前优惠券的商品所属的商铺
                $sql = "SELECT store_id FROM ".DB_PREFIX."goods WHERE goods_id={$coupon_info['pid']}";
                $goodsInfo = $model->getRow($sql);*/
            }
            //获取收货人的信息
            $address = $this->_getConsigneeInfo($model, $user_id);
            if (!$address) {
                $this->ajax_return(FLAG_ERROR, '您没有选择收货地址！');
            }
            $postalModel = m('postal');//实例化运费对象
            $postalModel->addinfo($address['region_id']);
            $pay_sn = $this->genOrderSn().rand(1000,9999).rand(100000, 999999);//生成总订单
            $num = 0;
            foreach($list['goods'] as $key=>$val) {
                $tmp = array();
                $f=0;
                foreach($val as $k=>$v) {
                    //此商铺内的订单
                    $tmp['user_id']     = $v['user_id'];
                    $tmp['user_name']   = $v['user_name'];
                    $tmp['email']       = $v['email'];
                    $tmp['store_id']    = $v['store_id'];
                    $tmp['store_name']  = $v['store_name'];
                    $v['real_price'] = ($v['discount'] == 1) ? $v['discount_spec_price'] : $v['price'];//是否是折扣价
                    //当前商铺的商品的总数量
                    $tmp['quantity'] = $tmp['quantity'] + $v['quantity'];
                    //订单总价
                    $tmp['order_amount'] = $tmp['order_amount'] + ($v['real_price'] * $v['quantity']);
                    //商品总价,真实价格,不算优惠价
                    $tmp['goods_amount'] = $tmp['goods_amount'] + ($v['price'] * $v['quantity']);
                    //供货总价
                    $tmp['supply_amount'] = $tmp['supply_amount'] + ($v['spec_supply_price'] * $v['quantity']);
                    //优惠总价
                    $tmp['discount_amount'] = $tmp['discount_amount'] + ($v['goods_amount'] - $v['order_amount']);
                    //计算邮费
                    if(!$postalModel->addgoods($v['goods_id'], $v['quantity'], $shipping_name)){
                        $this->ajax_return(FLAG_ERROR, $postalModel->error);
                    }
                    //$sql = "SELECT id FROM ".DB_PREFIX."activity_product WHERE pid=".$v['goods_id'];
                    if($coupon_id) {
                        $sql = "SELECT a.id FROM ".DB_PREFIX."activity_product a LEFT JOIN ".DB_PREFIX."coupons_participate b on a.aid=b.aid WHERE pid=".$v['goods_id']." AND b.id=".$coupon_id;
                        $coupons_rows = $model->getRow($sql);
                        $flag =  $coupons_rows['id']?true:false;
                        if($f==0 && $flag){
                            $coupons = true;
                            $f++;
                        }
                    }
                    $val[$k] = $v;
                }
                if(!$postal_info = $postalModel->expresslist()){
                    $this->ajax_return(FLAG_ERROR, $postalModel->error);
                }
                $tmp['shipping_fee'] = current($postal_info);//当前商铺订单的运费
                $tmp['order_amount'] = $tmp['order_amount'] + $tmp['shipping_fee'];//计算此订单的总金额
                $postalModel->cleargoods();//清除信息,计算下一个订单的信息
                //如何此优惠卷是当前店铺的,则算为当前店铺的订单优惠
                if ($coupon_id && ($num == 0) && isset($coupons) && $coupons) {
                    $tmp['discount_amount'] = floatval($tmp['discount_amount'] + $coupon_info['amount']);//当前商铺订单的优惠总价
                    $tmp['order_amount'] = floatval($tmp['order_amount'] - $coupon_info['amount']);//当前商铺的订单总价
                    $tmp['order_amount'] = ($tmp['order_amount'] < 0) ? 0 : $tmp['order_amount'];//防止订单金额为负数
                    //$num++;
                }
                //插入订单信息
                $orderModel = m('order');//实例化订单对象
                $order_id = $this->_handleOrderInfo($orderModel, $tmp, $pay_sn, $payment_id, $payment_name, $payment_code, $source, $postScript[$num]);
                if (!$order_id) {
                    $model->roll_back();
                    $this->ajax_return(FLAG_ERROR, '生成订单失败!');
                }
                //如果存在优惠券,则算为当前店铺的订单优惠
                if ($coupon_id && ($num == 0) && isset($coupons) && $coupons) {
                    // 修改优惠券使用
                    if ($coupon_id) {
                        $sql = "UPDATE ".DB_PREFIX."coupons_participate SET oid='{$order_id}',`status`=1,use_time=".time()." WHERE id={$coupon_id} LIMIT 1";
                        $flags = $model->query($sql);
                        if ($flags === false) {
                            $model->rollback();
                            $this->ajax_return(FLAG_ERROR, '修改优惠券信息失败！');
                        }
                    }
                    $num++;
                }
                //插入收货人的信息
                $orderExtmModel = m('orderextm');//实例化订单扩展表的信息
                $res = $this->_handleConsigneeInfo($orderExtmModel, $address, $order_id, $val['shipping_fee']);
                if ($res === false) {
                    $model->rollback();
                    $this->ajax_return(FLAG_ERROR, '插入收货人信息失败！');
                }
                //插入商品信息
                $orderGoodsModel = m('ordergoods');//订单商品表对象
                $rs = $this->_handelOrderGoodsInfo($orderGoodsModel, $order_id, $val);
                if ($rs === false) {
                    $model->roll_back();
                    $this->ajax_return(FLAG_ERROR, '添加订单商品失败!');
                }

                $order_amount = $order_amount + $tmp['order_amount'];
                $list['goods'][$key][0] = $tmp;
                $list['goods'][$key][1] = $val;

            }
            //如果是从购物车中来的商品,则删除购物车中的信息
            if ($type == 1) {
                $sql = "DELETE FROM ".DB_PREFIX."cart WHERE spec_id IN ({$spec_id}) AND user_id={$user_id}";
                $rss = $model->query($sql);
                if ($rss === false) {
                    $model->roll_back();
                    $this->ajax_return(FLAG_ERROR, '删除购物车中的商品失败!');
                }
            }
            $order_amount = $order_amount < 0 ? 0 : $order_amount;
            if ($order_amount == 0) {
                //使用了优惠券,直接生成订单,不需要支付
                $sql = "UPDATE `".DB_PREFIX."order` SET `status`=20 WHERE pay_sn={$pay_sn}";
                $ress = $model->query($sql);
                if ($ress === false) {
                    $model->roll_back();
                    $this->ajax_return(FLAG_ERROR, '生成订单失败失败!');
                }
            }
            $model->commit();
            //计算总邮费,总邮费是算在总金额中的
            $list['pay_sn'] = $pay_sn;//订单号
            $list['order_amount'] = sprintf("%.2f", $order_amount);
            $list['goods'] = array_merge(array(), $list['goods']);
        }
        return $list;
    }


    /**
     * 预览生成的订单,而不是添加订单
     * @return array
     * @author JYX
     * @date 2015/11/09
     */
    public function previewOrder() {
        $action = '预览生成的订单,而不是添加订单';
        setLogParameter($action);
        $method = strtoupper($_SERVER['REQUEST_METHOD']);
        if ($method != 'GET') {
            $this->ajax_return(FLAG_ERROR, '非法的请求！');
        }
        if (!$user_id = $this->checkLogin()) {
            $this->ajax_return(ERROR_LOGIN, '请您登陆！');
        }
//        $user_id = 539866;
        $type = $this->get_gp('type', 'G');//是否是购物车中的商品,1:是,0:不是,必传参数
        $spec_id = $this->get_gp('spec_id', 'G');//商品扩展属性的id,例如:1,3,5,56,23,必传的参数
        $quantity = $this->get_gp('quantity', 'G');//如果是单品过来的必传的参数
        $shipping_name = $this->get_gp('shipping_name', 'G');//快递名称,没有则不传
        $coupon_id = $this->get_gp('coupon_id', 'G');//优惠卷的id
        $type = $type ? 1 : 0;
        $quantity = $quantity ? intval($quantity) : 0;
        $shipping_name = $shipping_name ? $shipping_name : '';
        $model = m('order');
        $coupons_model = m('coupons');//优惠券对象
        $postal_model = m('postal');//实例化运费对象
        $order_amount = $total_shipping_fee = 0;//总运费
        $goodsInfo = $coupon_info = $data = array();
        //获取商品信息
        $list = $this->_getGoodsInfo($model, $type, $user_id, $spec_id, $quantity);
        if ($list) {
            //计算优惠卷
            if ($coupon_id) {
                $coupon_info = $coupons_model->getCouponsInfo($coupon_id);
                if (time() < $coupon_info['co_start_time'] && time() > $coupon_info['co_end_time']) {
                    $this->ajax_return(FLAG_ERROR, '您的优惠卷已经过期！');
                }
                if ($coupon_info['uid'] != $user_id) {
                    $this->ajax_return(FLAG_ERROR, '不是本人的优惠卷！');
                }
            }
            //获取收货人的信息
            $address = $this->_getConsigneeInfo($model, $user_id);
            if ($address) {//如果存在地址则计算运费信息
                $postal_model->addinfo($address['region_id']);
            }
            $keys = 0;
            foreach($list['goods'] as $key=>$val) {
                $tmp = array();
                $f=0;
                foreach($val as $k=>$v) {
                    $v['goods_image'] = $this->common->isMySelfImage($v['goods_image'], GOODS_S_IMG);
                    //此商铺内的订单
                    $v['discount_price'] = ($v['discount'] == 1) ? $v['discount_spec_price'] : $v['price'];//是否是折扣价
                    //当前商铺商品的数量
                    $tmp['quantity'] = $tmp['quantity'] + $v['quantity'];
                    //当前商铺订单总价
                    $tmp['order_amount'] = $tmp['order_amount'] + ($v['discount_price'] * $v['quantity']);
                    //计算邮费
                    if ($address) {//如果存在收货地址
                        if(!$postal_model->addgoods($v['goods_id'], $v['quantity'], $shipping_name)){
                            $this->ajax_return(FLAG_ERROR, $postal_model->error);
                        }
                    }
                    if($coupon_id) {
                        $sql = "SELECT a.id FROM ".DB_PREFIX."activity_product a LEFT JOIN ".DB_PREFIX."coupons_participate b on a.aid=b.aid WHERE pid=".$v['goods_id']." AND b.id=".$coupon_id;
                        $coupons_rows = $model->getRow($sql);
                        $flag =  $coupons_rows['id']?true:false;
                        if($f==0 && $flag){
                            $coupons = true;
                            $f++;
                        }
                    }
                    $val[$k] = $v;
                }
                if ($address) {//如果存在收货地址
                    if(!$postal_info = $postal_model->expresslist()){
                        $this->ajax_return(FLAG_ERROR, $postal_model->error);
                    }
                }
                $tmp['shipping_fee'] = $postal_info ? current($postal_info) : 0;//当前商铺订单的运费
                $tmp['order_amount'] = $tmp['order_amount'] + $tmp['shipping_fee'];//计算此商铺订单的总金额
                if ($address) {//如果存在收货地址
                    $postal_model->cleargoods();//清除信息,计算下一个订单的信息
                }
                //如果有优惠券,则只为第一个商铺减钱
                if ($coupon_id && ($keys == 0) && isset($coupons) && $coupons) {
                    $tmp['discount_amount'] = floatval($tmp['discount_amount'] + $coupon_info['amount']);//当前商铺订单的优惠总价
                    $tmp['order_amount'] = floatval($tmp['order_amount'] - $coupon_info['amount']);//当前商铺的订单总价
                    $tmp['order_amount'] = ($tmp['order_amount'] < 0) ? 0 : $tmp['order_amount'];//防止订单金额为负数
                    $keys++;
                }
                $order_amount = $order_amount + $tmp['order_amount'];//计算此订单的总金额
                $tmp['order_amount'] = sprintf("%.2f", $tmp['order_amount']);
                $tmp['store_id'] = $val[0]['store_id'];
                $tmp['store_name'] = $val[0]['store_name'];
                $temp = $val;
                unset($list['goods'][$key]);
                $list['goods'][$key][0] = $tmp;
                $list['goods'][$key][1] = $temp;

            }
        }
        $list['order_amount'] = sprintf("%.2f", $order_amount);
        $list['goods'] = array_merge(array(), $list['goods']);
        $this->ajax_return(FLAG_OK, '', $list);
    }

    /**
     * 判断商品的库存 1.4版本使用
     * @param $model
     * @param $user_id
     * @param $type
     * @param $spec_id
     * @param $quantity
     * @return bool
     * @author jyx
     * @date 2015/11/24
     */
    private function checkStocks($model, $user_id, $type, $spec_id, $quantity) {
        //获取商品的库存信息
        $sql = "SELECT SUM(stock) AS stock FROM ".DB_PREFIX."goods_spec WHERE spec_id IN ({$spec_id})";
        $spec = $model->getRow($sql);

        if ($type == 1) {//从购物车中买的商品
            //获取购物车中商品的数量
            $sql = "SELECT SUM(quantity) AS quantity FROM ".DB_PREFIX."cart WHERE spec_id IN ({$spec_id}) AND user_id={$user_id}";
            $cart = $model->getRow($sql);
            if ($cart['quantity'] > $spec['stock']) {
                $this->ajax_return(FLAG_ERROR, '您购买的商品库存不足!');
            }
        } else {//单个的商品
            if ($quantity < 1) {
                $this->ajax_return(FLAG_ERROR, '购买商品的数量必须大于1件!');
            }
            if ($quantity > $spec['stock']) {
                $this->ajax_return(FLAG_ERROR, '此商品库存不足!');
            }
        }
        return true;
    }
    /**
     * 获取订单商品的信息
     * @param $model
     * @param $type:是否是购物车中的商品,如果是为1,不是为0
     * @param $user_id:当前用户的id
     * @param $spec_id:商品扩展属性的id,例如:1,3,5,56,23
     * @param int $quantity:商品的数量
     * @return array
     * @author jyx
     * @date 2015/11/05
     */
    private function _getGoodsInfo($model, $type, $user_id, $spec_id, $quantity = 0) {
        $cart = $info = array();
        if ($type == 1) {
            //购物车中的多个商品,获取商品信息
            $sql = "SELECT ct.rec_id,ct.goods_id,ct.goods_name,ct.spec_id,ct.quantity,ct.goods_image,ct.specification,
                s.store_id,s.store_name,gs.price,gs.discount_spec_price,gs.is_show_discount,gs.spec_supply_price,
                g.act_start_time,g.act_end_time,m.user_id,m.user_name,m.email,m.phone_mob FROM ".DB_PREFIX."cart ct
                LEFT JOIN ".DB_PREFIX."store s ON ct.store_id=s.store_id LEFT JOIN ".DB_PREFIX."goods_spec gs
                ON gs.spec_id=ct.spec_id LEFT JOIN ".DB_PREFIX."goods g ON ct.goods_id=g.goods_id LEFT JOIN ".DB_PREFIX."member m
                ON ct.user_id=m.user_id WHERE ct.spec_id IN ({$spec_id}) AND ct.user_id={$user_id} ORDER BY s.store_id DESC";
            $tmp = $model->getAll($sql);
            if ($tmp) {
                foreach($tmp as $key=>$val) {
                    $val['specification'] = addslashes($val['specification']);
                    $cart['total_quantity'] = intval($cart['total_quantity'] + $val['quantity']); //计算商品总数量
                    $val['discount'] = $this->common->isAct($val, false);
                    $val['discount_price'] = ($val['discount'] == 1) ? ($val['discount_spec_price']) : ($val['price']);
                    $cart['order_amount'] = floatval($cart['order_amount'] + ($val['quantity'] * $val['discount_price']));//商品总价
                    $cart['goods'][$val['store_id']][] = $val;
                }
            }
        } else {
            //单个商品
            if ($quantity < 1) {
                $this->ajax_return(FLAG_ERROR, '购买数量不能小于1！');
            }
            //获取商品信息
            $sql = "SELECT gs.spec_id,gs.price,gs.discount_spec_price,gs.is_show_discount,gs.spec_1,gs.spec_2,s.store_id,
                s.store_name,g.goods_id,g.goods_name,g.default_image,g.spec_name_1,g.spec_name_2,g.act_start_time,g.act_end_time
                FROM ".DB_PREFIX."goods_spec gs LEFT JOIN ".DB_PREFIX."goods g ON gs.goods_id=g.goods_id LEFT JOIN ".DB_PREFIX."store s
                ON g.store_id=s.store_id WHERE gs.spec_id={$spec_id}";
            $tmp = $model->getRow($sql);
            if ($tmp) {
                if ($tmp['spec_name_1']) {
                    $tmp['specification'] = $tmp['spec_name_1'].':'.$tmp['spec_1'].' ';
                }
                if ($tmp['spec_name_2']) {
                    $tmp['specification'] .= $tmp['spec_name_2'].':'.$tmp['spec_2'].' ';
                }
                $tmp['specification'] = addslashes($tmp['specification']);
                $tmp['goods_image'] = $tmp['default_image'];
                $cart['total_quantity'] = $tmp['quantity'] = $quantity;
                $tmp['discount'] = $this->common->isAct($tmp, false);
                $tmp['discount_price'] = $tmp['discount'] == 1 ? $tmp['discount_spec_price'] : $tmp['price'];
                $cart['order_amount'] = ($cart['order_amount'] + $tmp['discount_price'] * $quantity);//订单总价
            }
            //获取用户信息
            $sql = "SELECT user_id,user_name,email,phone_mob FROM ".DB_PREFIX."member WHERE user_id={$user_id}";
            $temp = $model->getRow($sql);
            if ($temp && $tmp) {
                $info = array_merge($temp, $tmp);
            }
            $cart['goods'][$tmp['store_id']][] = $info;
        }
        return $cart;
    }

    /**
     * 生成一条订单信息,1.4版本
     * @param $orderModel:order表的对象
     * @param $goods
     * @param $pay_sn:总订单号
     * @param $payment_id:支付方式id
     * @param $payment_name
     * @param $payment_code
     * @param $source:支付来源
     * @param $post_script:每个子订单的留言信息
     * @return mixed
     * @author jyx
     * @date 2015/11/04
     */
    private function _handleOrderInfo($model, $goods, $pay_sn, $payment_id, $payment_name, $payment_code, $source, $post_script) {
        //按店铺来，一个店铺一个子订单
        $order_sn = $this->genOrderSn();//子订单
        $status = ORDER_PENDING;
        $time = time();
        $data = array(
            'pay_sn'        => $pay_sn,//总订单
            'order_sn'      => $this->genOrderSn(),//子订单
            'status'        => ORDER_PENDING,
            'add_time'      => time(),
            'payment_id'    => $payment_id,
            'payment_name'  => $payment_name,
            'payment_code'  => $payment_code,
            'source'        => $source,
            'seller_id'     => $goods['store_id'],
            'seller_name'   => addslashes($goods['store_name']),
            'buyer_id'      => $goods['user_id'],
            'buyer_name'    => addslashes($goods['user_name']),
            'buyer_email'   => $goods['email'],
            'goods_amount'  => $goods['goods_amount'],//商品总价
            'order_amount'  => $goods['order_amount'],//订单总价+运费金额
            'supply_amount' => $goods['supply_amount'],//供货总价
            'discount'      => $goods['discount_amount'],//折扣总价
            'postscript'    => addslashes($post_script),//当前订单的留言
        );
//        $sql = "INSERT INTO `".DB_PREFIX."order` (pay_sn,order_sn,status,add_time,payment_id,payment_name,payment_code,source,
//            seller_id,seller_name,buyer_id,buyer_name,buyer_email,goods_amount,order_amount,supply_amount,discount,postscript)
//            VALUES ('{$pay_sn}','{$order_sn}',{$status},{$time},{$payment_id},'{$payment_name}','{$payment_code}',{$source},
//            {$goods['store_id']},'{$goods['store_name']}',{$goods['user_id']},'{$goods['user_name']}','{$goods['email']}',
//            {$goods['goods_amount']},{$goods['order_amount']},{$goods['supply_amount']},{$goods['discount_amount']},'{$post_script}')";
//        return $model->insert_id();
        //插入订单信息
        return $model->add($data);
    }

    /**
     * 获取收货人的信息,1.4版本
     * @param $model
     * @param $user_id
     * @return mixed
     * @author jyx
     * @date 2015/11/04
     */
    private function _getConsigneeInfo($model, $user_id) {
        //获取收货人的信息,获取默认的信息
        $sql = "SELECT addr_id,user_id,consignee,region_id,region_name,address,zipcode,phone_mob
                FROM ".DB_PREFIX."address WHERE user_id={$user_id} AND state=1 LIMIT 1";
        return $model->getRow($sql);
    }

    /**
     * 插入收货人的信息
     * @param $model
     * @param $address
     * @param $order_id
     * @param $shipping_fee
     * @return mixed
     * @author jyx
     * @date 2015/11/04
     */
    private function _handleConsigneeInfo($model, $address, $order_id, $shipping_fee) {
        $data = array(
            'order_id'      => $order_id,
            'consignee'     => $address['consignee'],
            'region_id'     => $address['region_id'],
            'region_name'   => $address['region_name'],
            'address'       => $address['address'],
            'zipcode'       => $address['zipcode'],
            'phone_tel'     => $address['phone_tel'],
            'phone_mob'     => $address['phone_mob'],
            'shipping_fee'  => $shipping_fee,
        );
        return $model->add($data);
    }

    /**
     * 插入商品信息
     * @param $model
     * @param $order_id
     * @param $goods
     * @return mixed
     * @author jyx
     * @date 2015/11/04
     */
    private function _handelOrderGoodsInfo($model, $order_id, $goods) {
        //插入商品信息
        foreach($goods as $key=>$val) {
            $data[] = array(
                'order_id'      =>  $order_id,
                'goods_id'      =>  $val['goods_id'],
                'goods_name'    =>  addslashes($val['goods_name']),
                'spec_id'       =>  $val['spec_id'],
                'specification' =>  $val['specification'],
                'price'         =>  $val['real_price'],
                'supply_price'  =>  $val['spec_supply_price'],
                'quantity'      =>  $val['quantity'],
                'goods_image'   =>  $val['goods_image'],
            );
        }

        return $model->add($data);
    }

    /**
     * @param $user_id
     * @param $payment_id
     * @param $payment_name
     * @param $payment_code
     * @param $source
     * @return array
     * @author jyx
     * @date 2015/11/11
     */
    private function add_order($user_id, $payment_id, $payment_name, $payment_code, $source) {
        $wish_id = $this->get_gp('wish_id', 'P');//心愿单Id
        $spec_id = $this->get_gp('spec_id', 'P');
        $shipping_name = $this->get_gp('shipping_name', 'P');
        $coupon_id = $this->get_gp('coupon_id', 'P');
        $region_id = $this->get_gp('region_id', 'P');
        $spec_id = $spec_id ? intval($spec_id) : 0;
        $wish_id = $wish_id ? intval($wish_id) : 0;
        $coupon_id = $coupon_id ? intval($coupon_id) : 0;

        if (!$spec_id) {
            $this->ajax_return(FLAG_ERROR, '不存在的商品属性id！');
        }
        /* 获取收货人地址信息 */
        $consignee = $this->checkConsigneeInfo();

        /* 获取商品信息 */
        $goods_info = $this->getGoodsInfo();

        $order_model = m('order');
        $order_goods_model = m('ordergoods');
        $order_model->begin();//开启事物
        $postal_model = m('postal');
        $coupons_model = m('coupons');
        $postal_model->addinfo($consignee['region_id']);
        if($postal_model->error){
            $this->ajax_return(FLAG_ERROR, $postal_model->error);
        }

        /* 根据提供的商品信息生成订单 */
        foreach ($goods_info['items'] as $key=>$val) {
            /* 处理订单基本信息 */
            $base_info = $this->handleOrderInfo($val, $user_id, $payment_id, $payment_name, $payment_code, $source);

            //计算邮费
            $postal_model->addinfo($region_id);
            if(!$postal_model->addgoods($val['goods_id'], $val['quantity'], $shipping_name ? $shipping_name: null)){
                $this->ajax_return(FLAG_ERROR, $postal_model->error);
            }

            if(!$postal_info = $postal_model->expresslist()){
                $this->ajax_return(FLAG_ERROR, $postal_model->error);
            }

            $consignee['shipping_name'] = key($postal_info);
            $consignee['shipping_fee'] = current($postal_info);
            if ($consignee['shipping_fee']) {
                $base_info['order_amount'] += $consignee['shipping_fee'];
            }
            //计算优惠卷
            if ($coupon_id) {
                $coupon_info = $coupons_model->getCouponsInfo($coupon_id);
                if (time() < $coupon_info['co_start_time'] && time() > $coupon_info['co_end_time']) {
                    $this->ajax_return(FLAG_ERROR, '您的优惠卷已经过期！');
                }
                if ($coupon_info['uid'] != $user_id) {
                    $this->ajax_return(FLAG_ERROR, '不是本人的优惠卷！');
                }
                $base_info['discount'] = floatval($coupon_info['amount']);
                $base_info['order_amount'] = $base_info['order_amount'] - $base_info['discount'];
            }
//            if ($base_info['order_amount'] <= 0) {
//                $this->ajax_return(FLAG_ERROR, '订单金额不能小于0！');
//            }
            //处理收货人的信息
            $consignee_info = $this->handleConsigneeInfo($consignee);

            //检测商品库存量
            $bool = $this->checkStock($spec_id);
            if ($bool === false) {
                $this->ajax_return(FLAG_ERROR, '商品库存不足！');
            }

            //如果存在心愿单，并且心愿单已经完成，则此订单已经付款
            $tmps = array();
            if ($wish_id) {
                $tmps = $this->wish($wish_id, $user_id);
                if ($tmps['flag']) {
                    $base_info['status'] = ORDER_ACCEPTED;
                }
            }
            /* 插入订单信息 */
            $order_id    = $order_model->add($base_info);
            if (!$order_id) {
                $order_model->rollback();
                $this->ajax_return(FLAG_ERROR, '插入订单信息失败！');
            }

            // 修改优惠券使用
            if($coupon_id){
                if(!$order_model->query("UPDATE ".DB_PREFIX."coupons_participate SET oid='{$order_id}',`status`=1,use_time=".time()." WHERE id={$coupon_id} LIMIT 1")){
                    $order_model->rollback();
                    $this->ajax_return(FLAG_ERROR, '优惠券无法使用！');
                }
            }

            //查看心愿单是否要支付余额
            if ($wish_id) {
                //不需要付款
                if ($tmps['flag'] === true) {
                    //减少商品的库存,增加销量
                    $this->updateStock($wish_id,$tmps['goods_id'], $tmps['spec_id'],$base_info['order_sn']);
                }
                //需要支付余额
                if ($tmps['flag'] === false) {
                    if ($consignee['shipping_fee']) {
                        $base_info['order_amount'] = $tmps['price'] + $consignee['shipping_fee'];//添加运费
                    } else {
                        $base_info['order_amount'] = $tmps['price'];
                    }
                }
            }
            //更新心愿单信息的订单信息
            if ($wish_id && $order_id) {
                $sql = "UPDATE ".DB_PREFIX."wish SET order_sn='{$base_info['order_sn']}' WHERE wish_id={$wish_id}";
                $res = $order_model->query($sql);
                if ($res === false) {
                    $order_model->rollback();
                    $this->ajax_return(FLAG_ERROR, '更新心愿单信息失败！');
                }
            }

            /* 插入收货人信息 */
            $consignee_info['order_id'] = $order_id;
            $order_extm_model = m('orderextm');
            $flag = $order_extm_model->add($consignee_info);
            if ($flag === false) {
                $order_model->rollback();
                $this->ajax_return(FLAG_ERROR, '插入收货人信息失败！');
            }

            /* 插入商品信息 */
            $goods_items = array();
            foreach ($goods_info['items'] as $value)
            {
                $goods_items[] = array(
                    'order_id'      =>  $order_id,
                    'goods_id'      =>  $value['goods_id'],
                    'goods_name'    =>  $value['goods_name'],
                    'spec_id'       =>  $value['spec_id'],
                    'specification' =>  $value['specification'],
                    'price'         =>  $value['price'],
                    'supply_price'  =>  $value['supply_price'],
                    'quantity'      =>  $value['quantity'],
                    'goods_image'   =>  $value['goods_image'],
                );
                $body = $value['goods_name'];//商品名称
            }
            $rs = $order_goods_model->add(addslashes_deep($goods_items)); //防止二次注入
            if ($rs === false) {
                $order_model->rollback();
                $this->ajax_return(FLAG_ERROR, '插入商品信息失败！');
            }
            $base_info['body'] = $body;
            $bases_info[] = $base_info;
        }
        $order_model->commit();
        return $bases_info;
    }


    /**
     * 计算出是否要支付金额
     * @param $wish_id
     * @param $user_id
     * @return bool
     * @author jyx
     * @date 2015/07/30
     */
    private function wish($wish_id, $user_id) {
        $model = m('wish');
        //查询出商品的总金额
        $sql = "SELECT w.wish_id,w.goods_id,w.spec_id,gs.price FROM ".DB_PREFIX."wish w LEFT JOIN ".DB_PREFIX."goods_spec gs
				ON w.spec_id=gs.spec_id WHERE w.wish_id={$wish_id} AND user_id={$user_id}";
        $tmp = $model->getRow($sql);
        //查询出捐赠的总金额
        $sql = "SELECT SUM(donate_price) AS total_price FROM ".DB_PREFIX."wish_log WHERE wish_id={$wish_id} AND `status`=1";
        $temp = $model->getRow($sql);
        $price = floatval($tmp['price'] - $temp['total_price']);
        if ($price < 0 ) {
            $price = 0;
        }
        //如果金额相等，则去生成一条订单，入库,不需要支付！
        if ($temp['total_price'] == $tmp['price'] || $price == 0) {
            $tmp['flag'] = true;
        } else {
            $tmp['flag'] = false;
            $tmp['price'] = $price;
        }
        return $tmp;
    }


    /**
     * 更新销量和库存量
     * @param $wish_id
     * @param $goods_id
     * @param $spec_id
     * @param $order_sn
     * @return bool
     * @quthor jyx
     * @date 2015/07/31
     */
    private function updateStock($wish_id,$goods_id, $spec_id, $order_sn) {
        $model = m('wish');
        //更新心愿单信息
        $sql = "UPDATE ".DB_PREFIX."wish SET flag=1,order_sn='{$order_sn}' WHERE wish_id={$wish_id}";
        $flag = $model->query($sql);
        if ($flag === false) {
            $model->rollback();
            $this->ajax_return(FLAG_ERROR, '更新心愿单信息失败！');
        }
        //更新销量
        $sql = "SELECT goods_id FROM ".DB_PREFIX."goods_statistics WHERE goods_id={$goods_id}";
        if ($model->getRow($sql)) {
            $sql = "UPDATE ".DB_PREFIX."goods_statistics SET sales=sales+1 WHERE goods_id={$goods_id}";
            $rs = $model->query($sql);
        } else {
            $sql = "INSERT INTO ".DB_PREFIX."goods_statistics (goods_id,sales) VALUES ({$goods_id}, 1)";
            $rs = $model->query($sql);
        }
        //更新销量信息
        if ($rs === false) {
            $model->rollback();
            $this->ajax_return(FLAG_ERROR, '更新销量信息失败！');
        }
        //更新库存信息
        $sql = "UPDATE ".DB_PREFIX."goods_spec SET stock = stock-1 WHERE spec_id = {$spec_id}";
        $update = $model->query($sql);
        if ($update === false) {
            $model->rollback();
            $this->ajax_return(FLAG_ERROR, '更新库存信息失败！');
        }
        return true;
    }

    /**
     * 检测商品库存量
     * @param $spec_id
     * @return bool
     * @author jyx
     * @date 2015/08/03
     */
    private function checkStock($spec_id) {
        $model = m('goods');
        $sql = "SELECT stock FROM ".DB_PREFIX."goods_spec WHERE spec_id={$spec_id}";
        $tmp = $model->getRow($sql);
        if ($tmp['stock'] > 0) {
            return true;
        }
        return false;

    }



    /**
     * 获取外部传递过来的商品信息
     * @return array
     */
    private function getGoodsInfo() {
        $data = array(
            'type'          => 'material',  //商品类型
            'otype'         => 'normal',    //订单类型
            'allow_coupon'  => true,        //是否允许使用优惠券
        );
        //获取传递过来的商品扩展信息的spec_id
        $spec_id = $this->get_gp('spec_id', 'P');
        $quantity = $this->get_gp('quantity', 'P');
        $type = $this->get_gp('type', 'P');
        $type = $type ? 'cart' : '';
        $wish_id = $this->get_gp('wish_id', 'P');
        $user_id = $this->checkLogin();

        if (!$spec_id) {
            $this->ajax_return(FLAG_ERROR, '不存在的spec_id！');
        }
        $quantity = $quantity ? intval($quantity) : 1;
        if ($type == 'cart') {
            $sql = "SELECT c.*,s.store_name,s.owner_name FROM ".DB_PREFIX."cart c LEFT JOIN ".DB_PREFIX."store s ON c.store_id=s.store_id WHERE c.spec_id IN ({$spec_id})";
        } else {
            $sql = "SELECT goods_id FROM ".DB_PREFIX."goods_spec WHERE spec_id IN ({$spec_id}) GROUP BY goods_id";//查询出商品的goods_id
            $sql = "SELECT goods_id,goods_name,store_id,default_image,supply_price,is_act,discount_price,spec_qty FROM ".DB_PREFIX."goods WHERE goods_id IN ({$sql}) GROUP BY store_id";//查询出商铺的id
            $sql = "SELECT gs.*,g.store_id,g.goods_name,g.default_image,g.supply_price,g.is_act,g.discount_price,g.spec_qty FROM ".DB_PREFIX."goods_spec gs LEFT JOIN ($sql) AS g ON gs.goods_id=g.goods_id WHERE gs.spec_id IN ({$spec_id})";//关连商铺id和商品扩展信息
            $sql = "SELECT gs.*,s.store_name,s.owner_name FROM ({$sql}) gs LEFT JOIN ".DB_PREFIX."store s ON gs.store_id=s.store_id";//查询出商品和商铺的信息
        }
        $model = m('cart');
        $goods = $model->getAll($sql);

        if (!$goods) {
            $this->ajax_return(FLAG_ERROR, '您购买的商品信息不存在！');
        }

        $row = explode(',', $quantity);
        foreach ($goods as $key=>$val) {
            if ($type == 'cart') {
                //如果是从购物车中买商品是可以查询出商品数量的
                $val['subtotal'] = $val['quantity'] * $val['price'];         //当前商品小计总价
                $data['quantity'] += $val['quantity'];                       //商品总数量
                $data['amount'] += $val['subtotal'];                         //商品总价
            } else {
                $val['quantity'] = $row[$key];                              //商品的总数量
                if ($wish_id) {
                    //心愿单订单先走原价
                    $val['subtotal'] = $val['quantity'] * $val['price'];        //当前商品小计总价
                } else {
                    //如果使用优惠价
                    if ($val['is_show_discount'] == 2) {
                        $val['subtotal'] = $val['quantity'] * $val['discount_spec_price'];
                    } else {
                        $val['subtotal'] = $val['quantity'] * $val['price'];        //当前商品小计总价
                    }
                }

                $data['quantity'] += $val['quantity'];                      //商品的总数量
                $data['amount'] += $val['subtotal'];                        //商品总价
            }

            $val['supply_price'] = ($val['spec_supply_price'] > 0) ? floatval($val['spec_supply_price']) : floatval($val['supply_price']);
            $val['supply_price'] = $val['supply_price'] * $val['quantity'];//供货价*以数量
            if ($type == 'cart') {
                $val['goods_image'] = $val['goods_image'] ? $val['goods_image'] : Conf::get('default_goods_image');
            } else {
                $val['goods_image'] = $val['default_image'] ? $val['default_image'] : Conf::get('default_goods_image');
            }
            $val['type'] = 'material';
            $val['otype'] = 'normal';

            $data['items'][] = $val;
        }
        return $data;

    }

    /**
     * @param $goods_info
     * @param $user_id
     * @param $payment_id:支付方式的id
     * @param $payment_name
     * @param $payment_code
     * @param $source:订单的来源
     * @return array
     * @author jiayanxiu
     * @date 2015/11/11
     */
    private function handleOrderInfo($goods_info, $user_id, $payment_id, $payment_name, $payment_code, $source) {
        /* 默认都是待付款 */
        $order_status = ORDER_PENDING;

        /* 买家信息 */
        $sql = "SELECT user_name,email FROM ".DB_PREFIX."member WHERE user_id={$user_id}";
        $model = m('member');
        $user_info = $model->getRow($sql);
        /* 返回基本信息 @todo */
        $pay_sn = $this->genOrderSn();
        $return = array(
            'pay_sn'        =>  $pay_sn,
            'order_sn'      =>  $this->genOrderSn(),
            'type'          =>  $goods_info['type'],
            'extension'     =>  'normal',
            'seller_id'     =>  $goods_info['store_id'],
            'seller_name'   =>  addslashes($goods_info['store_name']),
            'buyer_id'      =>  $user_id,
            'buyer_name'    =>  addslashes($user_info["user_name"]),
            'buyer_email'   =>  $user_info["email"],
            'status'        =>  $order_status,
            'add_time'      =>  time(),
            'payment_id'    =>  $payment_id,
            'payment_name'  =>  $payment_name,
            'payment_code'  =>  $payment_code,
            'source'        =>  $source,
            'goods_amount'  =>  $goods_info['subtotal'],
            'order_amount'  =>  $goods_info['subtotal'],
            'supply_amount' =>  $goods_info['supply_price'],
            'discount'      =>  isset($goods_info['discount']) ? $goods_info['discount'] : 0,
            'postscript'    =>  $this->get_gp('postscript', 'P'),
        );
        return $return;
    }

    /**
     * 检测收货地址
     * @return mixed
     * @author jiayanxiu
     * @date 2015/02/06
     */
    private function checkConsigneeInfo() {
        $consignee['consignee'] = $this->get_gp('consignee', 'P');
        $consignee['region_name'] = $this->get_gp('region_name', 'P');
        $consignee['address'] = $this->get_gp('address', 'P');
        $consignee['phone_tel'] = $this->get_gp('phone_tel', 'P');
        $consignee['phone_mob'] = $this->get_gp('phone_mob', 'P');
        $consignee['region_id'] = (int)$this->get_gp('region_id', 'P');

        $consignee['region_id'] = $consignee['region_id'] ? intval($consignee['region_id']) : 0;
        //验证收货人信息填写是否完整
        if(!$consignee['region_id']){
            $this->ajax_return(FLAG_ERROR, '城市的id不正确！');
        }
        if (!$consignee['consignee']){
            $this->ajax_return(FLAG_ERROR, '收货人姓名不能为空！');
        }
        if (!$consignee['region_name']) {
            $this->ajax_return(FLAG_ERROR, '省级市地址不能为空！');
        }
        if (!$consignee['address']){
            $this->ajax_return(FLAG_ERROR, '详细收货地址不能为空！');
        }
        if (!$consignee['phone_tel'] && !$consignee['phone_mob']){
            $this->ajax_return(FLAG_ERROR, '请您至少填写一个联系方式！');
        }
        if ($consignee['phone_mob']) {
            if (strlen($consignee['phone_mob']) != 11) {
                $this->ajax_return(FLAG_ERROR, '手机号码长度为11位数字，请您重新填写！');
            }
            if (!$this->is_phone($consignee['phone_mob'])) {
                $this->ajax_return(FLAG_ERROR, '手机号码格式不正确，请您重新填写！');
            }
        }
        if ($consignee['phone_tel']) {
            if (!$this->is_mobile($consignee['phone_mob'])) {
                $this->ajax_return(FLAG_ERROR, '电话号码格式不正确，请您重新填写！');
            }
        }
        return $consignee;
    }

    /**
     * 处理收货人信息
     * @param $consignee
     * @return array|bool
     */
    private function handleConsigneeInfo($consignee) {
        //@todo 计算配送费用
        return array(
            'consignee'     =>  $consignee['consignee'],
            'region_id'     =>  $consignee['region_id'],
            'region_name'   =>  $consignee['region_name'],
            'address'       =>  $consignee['address'],
            'zipcode'       =>  $consignee['zipcode'],
            'phone_tel'     =>  $consignee['phone_tel'],
            'phone_mob'     =>  $consignee['phone_mob'],
//            'shipping_id'   =>  $consignee_info['shipping_id'],
            'shipping_name' =>  addslashes($consignee['shipping_name']),
            'shipping_fee'  =>  $consignee['shipping_fee'],
        );
    }

    /**
     * 生成订单号
     * @return string
     * @author jiayanxiu
     * @date 2015/02/02
     */
    private function genOrderSn() {
        /* 选择一个随机的方案 */
        mt_srand((double) microtime() * 1000000);
        $timestamp = gmtime();
        $y = date('y', $timestamp);
        $z = date('z', $timestamp);
        $order_sn = $y . str_pad($z, 3, '0', STR_PAD_LEFT) . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
        $model = m('order');
        $sql = "SELECT order_id FROM `".DB_PREFIX."order` WHERE order_sn={$order_sn}";
        $orders = $model->getRow($sql);
        if (empty($orders)) {
            /* 否则就使用这个订单号 */
            return $order_sn;
        }
        /* 如果有重复的，则重新生成 */
        return $this->genOrderSn();
    }



}